package service;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Date;

import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import util.StringHelper;
import util.TagHelper;

import entity.Author;
import entity.IpSocket;
import entity.Question;
import entity.Tag;

import model.AuthorModel;
import model.QuestionModel;
import model.TagModel;

public class FromStackOverFlowBaby {

	QuestionModel questionModel;
	TagModel tagModel;
	AuthorModel authorModel;
	Date date;
	Document doc;

	public Question searchAndGetQuestion(String alias) {
		questionModel = new QuestionModel();
		IpSocket mySocket = new IpSocket();
		try {
			// search question from stackoverflow with alias.
			doc = util.SocketContentHandle.getSiteContentBySocket(
					"stackoverflow.com", "",
					"http://stackoverflow.com/search?q=" + alias,
					mySocket.getIp4StackOverFlow());
			// get link of question.
			Elements searchResult = doc.getElementsByClass("question-summary");
			if (searchResult.size() > 0) {
				String url = searchResult.get(0).select("h3").select("a")
						.attr("href");
				url = "http://stackoverflow.com/" + url;
				// get question's content.
				doc = util.SocketContentHandle.getSiteContentBySocket(
						"stackoverflow.com", "", url,
						mySocket.getIp4StackOverFlow());
				Question obj = new Question();
				
				obj.setUrl(url);

				// get answer.
				Elements answer = doc.select(".answer");
				Element tempAnswer = null;
				Element answerContent = null;
				if (answer.size() > 0) {
					boolean had = false;
					for (Element element : answer) {
						Element e = element.select(
								"span[class=vote-accepted-on]").first();
						if (e != null && e.text().equalsIgnoreCase("accepted")) {
							answerContent = element;
							had = true;
							break;
						} else {
							if (!had) {
								tempAnswer = element;
								had = true;
							}
						}
					}
				} else {
					System.out.println("have no answer");
					return null;
				}

				if (answerContent != null) {
					obj.setContentAnswer(answerContent.select(".post-text")
							.html());
					obj = addAnswerAuthor(obj,
							answerContent.select(".user-details").first()
									.select("a").text());
				} else {
					obj.setContentAnswer(tempAnswer.select(".post-text").html());
					obj = addAnswerAuthor(
							obj,
							tempAnswer.select(".user-details").first()
									.select("a").text());
				}
				// alias
				String[] splitted = url.split("/");
				String newAlias = splitted[splitted.length-1];

				// title.
				obj.setTitle(doc.select("#question-header").text());
				obj.setAlias(newAlias);

				// content.
				Elements question = doc.select("#question");
				String content = question.select(".post-text").html();
				obj.setContent(content);

				// tag.
				Elements tags = question.select(".post-tag");
				obj = addTags(tags, obj);
				obj = addOtherTags(obj);

				// question's author.
				String author = question.select(".user-details").select("a")
						.text();
				obj = addQuestionAuthor(obj, author);

				date = new Date();
				obj.setLastUpdateDate(date);
				obj.setDoc(date);
				obj.setHadContent(1);
				obj.setLang("en");

				for (String tag : obj.getTags()) {
					System.out.println(tag);
				}
				System.out.println("Other tag : ");
				for (String otherTag : obj.getOtherTags()) {
					System.out.println(otherTag);
				}
				questionModel.save(obj);
				return obj;
			} else {
				System.out.println("have no result search");
				return null;
			}
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	private Question addAnswerAuthor(Question obj, String answerAuthor) {
		String aliasAnswer = StringHelper.replace(answerAuthor);
		authorModel = new AuthorModel();
		Author ans = authorModel.findByAlias(aliasAnswer);
		if (ans.getAlias() != null && !ans.getAlias().equals("")) {
			ans.setCountAnswer(ans.getCountAnswer() + 1);
			authorModel.save(ans);
		} else {
			int randomAvatar = 1 + (int) (Math.random() * 33);
			Author a = new Author();
			a.setAvatar("author" + randomAvatar + ".png");
			a.setName(answerAuthor);
			a.setAlias(aliasAnswer);
			a.setCountAnswer(1);
			a.setCountQuestion(0);
			authorModel.save(a);
		}
		obj.setAliasAuthorAnswer(aliasAnswer);
		return obj;
	}

	private Question addQuestionAuthor(Question obj, String questionAuthor) {
		String aliasAuthor = StringHelper.replace(questionAuthor);
		authorModel = new AuthorModel();
		Author ask = authorModel.findByAlias(aliasAuthor);
		if (ask.getAlias() != null && !ask.getAlias().equals("")) {
			int curr = ask.getCountQuestion();
			ask.setCountQuestion(curr + 1);
			authorModel.save(ask);
		} else {
			int randomAvatar = 1 + (int) (Math.random() * 33);
			Author author = new Author();
			author.setAvatar("author" + randomAvatar + ".png");
			author.setName(questionAuthor);
			author.setAlias(aliasAuthor);
			author.setCountAnswer(0);
			author.setCountQuestion(1);
			authorModel.save(author);
		}
		obj.setAliasAuthor(aliasAuthor);
		return obj;
	}

	private Question addTags(Elements tags, Question obj) {

		// Tag handle, get all tag name from original
		ArrayList<String> temp = new ArrayList<String>();
		if (tags.size() > 0) {
			for (int i = 0; i < tags.size(); i++) {
				String value = tags.get(i).text().toLowerCase();
				temp.add(value);
			}
		}
		// from o2tv
		Document burnDoc = TagHelper.help(doc);
		Elements myTags = burnDoc.select(".tag");

		if (myTags.size() > 0) {
			for (int i = 0; i < myTags.size(); i++) {
				String value = myTags.get(i).text().toLowerCase();
				if (!temp.contains(value)) {
					temp.add(value);
				}
			}
		}
		int tempSize = 0;
		if (temp.size() > 30) {
			tempSize = 30;
		} else {
			tempSize = temp.size();
		}
		tagModel = new TagModel();
		if (temp.size() > 0) {
			for (int i = 0; i < tempSize; i++) {
				if (!temp.get(i).equals("m") && !temp.get(i).equals("t")) {

					String aliasTag = StringHelper.tag(temp.get(i));
					obj.getTags().add(aliasTag);

					Tag had = tagModel.find(aliasTag);
					if (had.getAlias() != null && !had.getAlias().equals("")) {
						had.setCount(had.getCount() + 1);
						tagModel.save(had);
					} else {
						Tag tag = new Tag();
						tag.setName(temp.get(i));
						tag.setAlias(aliasTag);
						tag.setCount(1);
						tagModel.save(tag);
					}
				}
			}
		}
		return obj;
	}

	private Question addOtherTags(Question obj) {
		tagModel = new TagModel();
		while (obj.getOtherTags().size() <= 30) {
			boolean had = false;
			Tag random = tagModel.random();
			for (String tag : obj.getTags()) {
				if (tag.equals(random.getAlias())) {
					had = true;
				}
			}
			if (!had) {
				obj.getOtherTags().add(random.getAlias());
			}
		}
		return obj;
	}

	public static void main(String[] args) {
		FromStackOverFlowBaby dt = new FromStackOverFlowBaby();
		Question q = dt.searchAndGetQuestion("jquery-css-selector-combined-with-this");
		if (q != null)
			System.out.println("ok");
		else {
			System.out.println("not ok");
		}
	}
}
